package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.aliyun.iot20180120.models.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.base.ResponseResult;
import com.zzyl.dto.DeviceDto;
import com.zzyl.dto.DevicePageQueryDto;
import com.zzyl.entity.Device;
import com.zzyl.entity.DevicePropertyStatus;
import com.zzyl.entity.NursingPlan;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeviceMapper;
import com.zzyl.properties.AliIoTConfigProperties;
import com.zzyl.service.DeviceService;
import com.zzyl.utils.StringUtils;
import com.zzyl.vo.DeviceVo;
import com.zzyl.vo.ProductVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.aliyun.iot20180120.Client;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DeviceServiceImpl implements DeviceService {
    @Autowired
    private Client client;
    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private DeviceMapper deviceMapper;

    @Override
    public void syncProductList() {
        QueryProductListRequest request = new QueryProductListRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        request.setCurrentPage(1);
        request.setPageSize(100);
        QueryProductListResponse response = null;
        try {
            response = client.queryProductList(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_LIST_PRODUCT_ERROR);
        }

        if (!response.getBody().success) {
            throw new BaseException(BasicEnum.IOT_LIST_PRODUCT_ERROR);
        }

        List<ProductVo> productVoList = response.getBody().getData().getList().getProductInfo().stream().map(
                p -> BeanUtil.toBean(p, ProductVo.class)
        ).collect(Collectors.toList());

        redisTemplate.opsForValue().set("iot:all_product", JSONUtil.toJsonStr(productVoList));

    }


    @Override
    public List<ProductVo> allProduct() {
        List<ProductVo> list = null;
        try {
            String jsonStr = redisTemplate.opsForValue().get("iot:all_product");
            if (StringUtils.isEmpty(jsonStr)) {
                return Collections.emptyList();
            }
            list = JSONUtil.toList(jsonStr, ProductVo.class);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_LIST_PRODUCT_ERROR);
        }
        return list;
    }

    @Override
    public void RegisterDevice(DeviceDto deviceDto) {
        //判断重复
        if (deviceMapper.selectByName(deviceDto.getDeviceName()) > 0) {
            throw new BaseException(BasicEnum.DEVICE_NAME_EXIST);
        }
        //新增设备
        RegisterDeviceResponse registerDeviceResponse;
        RegisterDeviceRequest registerDeviceRequest = deviceDto.getRegisterDeviceRequest();
        registerDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        try {
            registerDeviceResponse = client.registerDevice(registerDeviceRequest);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        //接口是否掉调通
        if (!registerDeviceResponse.getBody().success) {
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }

        //设置设备
        Device device = BeanUtil.toBean(deviceDto, Device.class);
        device.setIotId(registerDeviceResponse.getBody().getData().getIotId());
        //产品名称
        QueryProductRequest queryProductRequest = new QueryProductRequest();
        queryProductRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        queryProductRequest.setProductKey(deviceDto.getProductKey());
        QueryProductResponse queryProductResponse;
        try {
            queryProductResponse = client.queryProduct(queryProductRequest);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        if (queryProductResponse.getBody().success) {
            device.setProductName(queryProductResponse.getBody().getData().productName);
        }
        //判断0/1
        if (device.getLocationType() == 0) {
            device.setPhysicalLocationType(-1);
        }
        //保存数据库
        try {
            deviceMapper.insertSelective(device);
        } catch (Exception e) {
            //失败，删除
            DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
            deleteDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
            deleteDeviceRequest.setProductKey(device.getProductKey());
            deleteDeviceRequest.setDeviceName(device.getDeviceName());
            deleteDeviceRequest.setIotId(registerDeviceResponse.getBody().getData().getIotId());
            try {
                client.deleteDevice(deleteDeviceRequest);
            } catch (Exception ex) {
                throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
            }
            throw new BaseException(BasicEnum.LOCATION_BINDING_PRODUCT);
        }

    }

    @Override
    public PageResponse<DeviceVo> selectByPage(DevicePageQueryDto devicePageQueryDto) {
        PageHelper.startPage(devicePageQueryDto.getPageNum(), devicePageQueryDto.getPageSize());
        Page<DeviceVo> deviceVos = deviceMapper.selectByPage(devicePageQueryDto);
        System.out.println(deviceVos);
        return PageResponse.of(deviceVos, DeviceVo.class);
    }

    @Override
    public DeviceVo queryDeviceDetail(QueryDeviceDetailRequest request) {
        //iot查询
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDeviceDetailResponse queryDeviceDetailResponse;
        try {
            queryDeviceDetailResponse = client.queryDeviceDetail(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        if (!queryDeviceDetailResponse.getBody().success) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        //数据库查询
        DeviceVo deviceVo = deviceMapper.selectByIotId(request.getIotId());
        //合并
        QueryDeviceDetailResponseBody.QueryDeviceDetailResponseBodyData data = queryDeviceDetailResponse.getBody().getData();
        BeanUtil.copyProperties(data, deviceVo, CopyOptions.create().ignoreNullValue());
        return deviceVo;
    }

    @Override
    public ResponseResult queryDevicePropertyStatus(QueryDevicePropertyStatusRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDevicePropertyStatusResponse response;
        try {
            response = client.queryDevicePropertyStatus(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_PROPERTY_STATUS_ERROR);
        }
        return ResponseResult.success(response.getBody().getData());
    }

    @Override
    public ResponseResult queryThingModelPublished(QueryThingModelPublishedRequest request) {
        QueryThingModelPublishedRequest queryThingModelPublishedRequest = new QueryThingModelPublishedRequest();
        queryThingModelPublishedRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        queryThingModelPublishedRequest.setProductKey(request.getProductKey());
        QueryThingModelPublishedResponse queryThingModelPublishedResponse;
        try {
            queryThingModelPublishedResponse = client.queryThingModelPublished(queryThingModelPublishedRequest);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        if(!queryThingModelPublishedResponse.getBody().success){
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_PROPERTY_STATUS_ERROR);
        }
        return ResponseResult.success(queryThingModelPublishedResponse.getBody().getData());
    }

    @Override
    public void updateDevice(DeviceDto deviceDto) {

    }

    @Override
    public void deleteDevice(DeleteDeviceRequest request) {

    }

}
